package com.huqing.icu.service.app.impl;

import com.huqing.icu.base.IdReq;
import com.huqing.icu.base.PagingDto;
import com.huqing.icu.base.redis.Redis;
import com.huqing.icu.base.redis.annotation.RedisLock;
import com.huqing.icu.client.UserFeignClient;
import com.huqing.icu.constants.CacheLockConstants;
import com.huqing.icu.dto.CommunityPostDto;
import com.huqing.icu.dto.CommunityPostQueryDto;
import com.huqing.icu.enums.BusinessConstants;
import com.huqing.icu.enums.community.UserPostBehaviorEnum;
import com.huqing.icu.exceptions.BusinessException;
import com.huqing.icu.inout.req.app.CommunityPostAddReq;
import com.huqing.icu.inout.req.app.CommunityPostListQueryReq;
import com.huqing.icu.inout.resp.app.CommunityPostListQueryResp;
import com.huqing.icu.inout.resp.app.CommunityPostQueryDetailResp;
import com.huqing.icu.inout.resp.user.UserInfoQueryResp;
import com.huqing.icu.mapper.CommunityPostMapper;
import com.huqing.icu.mapper.CommunityPostStatisticsMapper;
import com.huqing.icu.mapper.UserPostBehaviorMapper;
import com.huqing.icu.model.CommunityPost;
import com.huqing.icu.model.CommunityPostStatistics;
import com.huqing.icu.model.UserPostBehavior;
import com.huqing.icu.service.app.ICommunityPostService;
import com.huqing.icu.service.app.IUserPostPanelService;
import com.huqing.icu.utils.CopyUtils;
import com.huqing.icu.utils.JsonUtils;
import com.huqing.icu.utils.PageUtils;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description 社区帖子接口实现类
 * @Author huqing
 * @Date 2025/4/6 20:49
 **/
@Service
public class CommunityPostServiceImpl implements ICommunityPostService {

    @Autowired
    private IUserPostPanelService iUserPostPanelService;
    @Resource
    private CommunityPostMapper communityPostMapper;
    @Resource
    private UserPostBehaviorMapper userPostBehaviorMapper;
    @Resource
    private CommunityPostStatisticsMapper communityPostPanelMapper;
    @Autowired
    private Redis redis;

    @Resource
    private UserFeignClient userFeignClient;

    /**
     * 新增帖子
     *
     * @param addReq
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer addPost(CommunityPostAddReq addReq) {
        CommunityPost communityPost = CopyUtils.copy(addReq, CommunityPost.class);
        if (CollectionUtils.isNotEmpty(addReq.getImgList())) {
            String imgStr = JsonUtils.obj2String(addReq.getImgList());
            communityPost.setImgStr(imgStr);
        }

        int result = communityPostMapper.insert(communityPost);
        return result;
    }

    /**
     * 查询帖子列表
     *
     * @param listQueryReq
     * @param userId
     * @return
     */
    @Override
    public PagingDto<CommunityPostListQueryResp> queryList(CommunityPostListQueryReq listQueryReq, Long userId) {

        int startIndex = PageUtils.getPageStartIndex(listQueryReq.getPageIndex(), listQueryReq.getPageSize());
        CommunityPostQueryDto queryDto = CopyUtils.copy(listQueryReq, CommunityPostQueryDto.class);
        queryDto.setStartIndex(startIndex);

        //查询有多少个
        Integer count = communityPostMapper.getNumByCondition(queryDto);
        if (count == 0) {
            return new PagingDto(Collections.emptyList(), 0, 0);
        }
        List<CommunityPostDto> communityPostsDtoList = communityPostMapper.selectByCondition(queryDto);

        //关联点赞、收藏等数据
        communityPostsDtoList = linkUserBehavior(communityPostsDtoList, userId);
        List<CommunityPostListQueryResp> respList = CopyUtils.copyOriginListToDestList(communityPostsDtoList, CommunityPostListQueryResp.class);

        PagingDto pagingDto = new PagingDto<>(respList, PageUtils.getTotalPage(count, listQueryReq.getPageSize()), count);
        return pagingDto;
    }

    /**
     * 查询帖子详情
     *
     * @param postId
     * @param userId
     * @return
     */
    @Override
    public CommunityPostQueryDetailResp queryDetail(Long postId, Long userId) {
        CommunityPost communityPost = communityPostMapper.selectById(postId);
        CommunityPostDto communityPostDto = CopyUtils.copy(communityPost, CommunityPostDto.class);

        //填充一些数据，比如是否点赞、收藏，点赞数、收藏数
        List<CommunityPostDto> postDtoList = linkUserBehavior(Arrays.asList(communityPostDto), userId);
        CommunityPostQueryDetailResp queryDetailResp = CopyUtils.copy(postDtoList.get(0), CommunityPostQueryDetailResp.class);

        //每进一次帖子详情，浏览数就得+1，浏览人数可能+1
        iUserPostPanelService.incrViewNum(postId);

        iUserPostPanelService.incrViewPersonNum(postId, userId);

        return queryDetailResp;
    }

    /**
     * 删除帖子
     *
     * @param id
     * @param userId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer delete(Long id, Long userId) {

        //每个人只能删除自己的帖子
        Integer result = communityPostMapper.delete(id, userId);
        if (result < 0) {
            throw new BusinessException(BusinessConstants.PARAMETER_INVALID.getCode(), "删除失败，请检查");
        }
        return 1;
    }


    /**
     * 点赞或取消点赞帖子
     *
     * @param postId
     * @param userId
     * @return
     */
    @RedisLock(key = CacheLockConstants.CommunityPostPrefix.USER_LIKE_POST, waitTime = 3000)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer like(Long postId, Long userId) {

        //1 查询用户是否已经点赞了
        UserPostBehavior userPostLike = userPostBehaviorMapper.selectOne(userId, postId, UserPostBehaviorEnum.LIKE.getType());

        Boolean isIncrLikeNum = userPostLike == null ? true : false;

        //如果查不到，说明没点赞，则新增点赞记录
        if (userPostLike == null) {
            userPostLike = new UserPostBehavior();
            userPostLike.setUserId(userId);
            userPostLike.setPostId(postId);
            userPostBehaviorMapper.insert(userPostLike);
        } else {
            //如果查到了，说明有点赞记录了，需要删除
            userPostBehaviorMapper.deleteById(userPostLike.getId());
        }

        //点赞数+1或-1
        iUserPostPanelService.incrOrDecrLikeNum(postId, isIncrLikeNum);

        return 1;
    }

    /**
     * 收藏或取消收藏帖子
     *
     * @param postId
     * @param userId
     * @return
     */
    @RedisLock(key = CacheLockConstants.CommunityPostPrefix.USER_FAVORITE_POST, waitTime = 3000)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer favorite(Long postId, Long userId) {
        //1 查询用户是否已经收藏了
        UserPostBehavior userPostFavorite = userPostBehaviorMapper.selectOne(userId, postId, UserPostBehaviorEnum.FAVORITE.getType());

        //如果查不到，说明没收藏，则新增收藏记录
        Boolean isIncrFavoriteNum = userPostFavorite == null ? true : false;
        if (userPostFavorite == null) {
            userPostFavorite = new UserPostBehavior();
            userPostFavorite.setUserId(userId);
            userPostFavorite.setPostId(postId);
            userPostBehaviorMapper.insert(userPostFavorite);
        } else {
            //如果查到了，说明有收藏记录了，需要删除
            userPostBehaviorMapper.deleteById(userPostFavorite.getId());
        }

        //收藏数+1或-1
        iUserPostPanelService.incrOrDecrFavoriteNum(postId, isIncrFavoriteNum);
        return 1;
    }

    /**
     * 关联用户的行为，比如点赞数、收藏数等
     *
     * @param communityPostsDtoList
     * @param userId
     * @return
     */
    private List<CommunityPostDto> linkUserBehavior(List<CommunityPostDto> communityPostsDtoList, Long userId) {

        List<Long> postIdList = communityPostsDtoList.stream().map(CommunityPostDto::getId).collect(Collectors.toList());

        List<Long> userIdList = communityPostsDtoList.stream().map(CommunityPostDto::getUserId).distinct().collect(Collectors.toList());


        Map<Long, UserPostBehavior> userPostLikeMap = null;
        Map<Long, UserPostBehavior> userPostFavoriteMap = null;

        //如果当前登录用户ID不为空，则查下用户是否点赞、收藏
        if (userId != null) {
            List<Integer> behaviorList = Arrays.asList(UserPostBehaviorEnum.LIKE.getType(), UserPostBehaviorEnum.FAVORITE.getType());
            List<UserPostBehavior> userPostBehaviorList = userPostBehaviorMapper.selectList(userId, postIdList, behaviorList);

            if (CollectionUtils.isNotEmpty(userPostBehaviorList)) {
                userPostLikeMap = userPostBehaviorList.stream().filter(o -> UserPostBehaviorEnum.LIKE.getType().equals(o.getBehavior())).collect(Collectors.toMap(UserPostBehavior::getPostId, p -> p));
                userPostFavoriteMap = userPostBehaviorList.stream().filter(o -> UserPostBehaviorEnum.FAVORITE.getType().equals(o.getBehavior())).collect(Collectors.toMap(UserPostBehavior::getPostId, p -> p));
            }
        }

        //查询帖子的点赞数、收藏数等面板数据
        List<CommunityPostStatistics> postPanelList = communityPostPanelMapper.selectBatchIds(postIdList);
        Map<Long, CommunityPostStatistics> postPanelMap = null;
        if (CollectionUtils.isNotEmpty(postPanelList)) {
            postPanelMap = postPanelList.stream().collect(Collectors.toMap(CommunityPostStatistics::getPostId, p -> p));
        }

        // 通过feign,查询这些帖子的作者信息
        IdReq idReq = new IdReq();
        idReq.setIdList(userIdList);
        List<UserInfoQueryResp> userList = userFeignClient.queryList(idReq);
        Map<Long, UserInfoQueryResp> userMap = null;
        if (CollectionUtils.isNotEmpty(userList)) {
            userMap = userList.stream().collect(Collectors.toMap(UserInfoQueryResp::getUserId, p -> p));
        }


        //遍历每条帖子，看当前登录人是否点赞、收藏过
        for (CommunityPostDto communityPostDto : communityPostsDtoList) {
            Integer isLike = userPostLikeMap != null && userPostLikeMap.containsKey(communityPostDto.getId()) ? 1 : 0;
            Integer isFavorite = userPostFavoriteMap != null && userPostFavoriteMap.containsKey(communityPostDto.getId()) ? 1 : 0;
            communityPostDto.setIsLike(isLike);
            communityPostDto.setIsFavorite(isFavorite);

            //点赞数、收藏数等
            if (postPanelMap != null && postPanelMap.containsKey(communityPostDto.getId())) {
                CommunityPostStatistics postPanel = postPanelMap.get(communityPostDto.getId());
                Long likeNum = postPanel.getActualLikeNum();
                Long favoriteNum = postPanel.getActualFavoriteNum();
                Long viewUserNum = postPanel.getActualViewUserNum();
                Long viewNum = postPanel.getActualViewNum();
                communityPostDto.setActualLikeNum(likeNum);
                communityPostDto.setActualFavoriteNum(favoriteNum);
                communityPostDto.setActualViewUserNum(viewUserNum);
                communityPostDto.setActualViewNum(viewNum);
            }

            //用户姓名、头像等
            if (userMap != null && userMap.containsKey(communityPostDto.getUserId())) {
                UserInfoQueryResp user = userMap.get(communityPostDto.getUserId());
                communityPostDto.setNickname(user.getNickname());
                communityPostDto.setAvatar(user.getAvatar());
            }
        }
        return communityPostsDtoList;
    }

}
